<?php

namespace app\command;

use app\framework\lib\Log;
use app\framework\lib\Redis;
use app\service\CurrencyKline;


class klineMin extends Command
{
    // 修正Cron表达式（6字段：秒 分 时 日 月 周，此处表示每分钟执行一次）
    public $cron = "* */5 * * * *";

    // API地址常量，使用sprintf占位符更清晰
    private const API_URL = "https://api.huobi.pro/market/detail?symbol=%susdt";

    // Redis键名前缀常量，便于维护
    private const REDIS_KEY_PREFIX = "market.%susdt.kline.detail";

    /**
     * 执行逻辑
     */
    public function run()
    {
        try {
            $this->lock(); // 加锁放在try块，确保解锁执行

            $coins = $this->getValidCoins();

            foreach ($coins as $coin) {
                $this->processCoin($coin);
                usleep(500000); // 500ms间隔，避免API限流（替代sleep(2)，更灵活）
            }
        } catch (\Exception $e) {
            Log::error("KlineMin执行异常: " . $e->getMessage());
        } finally {
            Log::info("KlineMin执行完毕");
            $this->unlock(); // 确保无论成功失败都解锁
        }
    }

    /**
     * 获取并过滤有效的货币列表
     * @return array
     */
    private function getValidCoins(): array
    {
        $coins = CurrencyKline::getMarketList();
        // 过滤空值和非字符串元素
        return array_filter($coins, function ($coin) {
            return is_string($coin) && !empty(trim($coin));
        });
    }

    /**
     * 处理单个货币的K线数据
     * @param string $coin 货币代码
     */
    private function processCoin(string $coin): void
    {


        $data = self::httpGet($coin);

        // 处理数据并更新昨日K线
        $this->update24HoursKline($data, $coin);
    }



    /**
     * 更新昨日K线数据到Redis
     * @param array $data K线数据数组
     * @param string $yesterdayKey Redis键名
     * @param string $currentDate 当前日期
     */
    private function update24HoursKline(array $data, string $code): void
    {
        // 遍历K线数据（原array_chunk逻辑有误，直接遍历元素）
        $key = sprintf(self::REDIS_KEY_PREFIX, $code);
        Redis::set( $key, serialize($data));

    }

    /**
     * 发送HTTP请求获取数据（使用cURL更可靠）
     * @param string $coin 货币代码
     * @return array|null 成功返回数据数组，失败返回null
     */
    public static function httpGet($coin)
    {
        $url = sprintf(self::API_URL,$coin);
        try{
            $data = file_get_contents($url);
            if (empty($data)) {
                throw new \Exception("Failed to read: $url");
            }
            $data = json_decode($data,true);;
            if ($data===false) {
                return false;
            }
            if (empty($data["status"])) {
                return;
            }
            if ($data["status"]=="ok") {
                return $data['tick'];
            }

        } catch (\Exception $e) {
            Log::error("http获取火币错误".$e->getMessage());
        }
    }
}